package com.seestech.sell.common.utils;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.StaxDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.thoughtworks.xstream.io.xml.XppDriver;

import java.io.Writer;
import java.util.List;

/**
 * Created by idiot on 2017/6/26.
 */
public class XStreamUtils {

    /**
     * Java对象转Xml字符串（序列化）
     * @param object
     * @return
     */
    public static String beanToXml(Object object){
        XStream stream = new XStream(new StaxDriver() {
            public HierarchicalStreamWriter createWriter(Writer out) {
                return new PrettyPrintWriter(out) {

                    public void startNode(String name) {
                        // 去掉包名
                        if (name.indexOf(".") > -1) {
                            name = name.substring(name.lastIndexOf(".") + 1);
                        }
                        super.startNode(name);
                    };
                };
            }

            protected void write(QuickWriter writer, String text) {
                writer.write("<![CDATA[");
                writer.write(text);
                writer.write("]]>");
            }

        });
        return stream.toXML(object);
    }

    /**
     * Xml字符串转Java对象（反序列化）
     * @param xml
     * @param rootName 根元素名称
     * @param rootType 根元素对应的Java类型
     * @param collectionTypes 集合类型
     * @return
     */
    public static Object xmlToBean(String xml, String rootName, Class<?> rootType,
                           List<Class<?>> collectionTypes){
        XStream stream = new XStream();
        stream.alias(rootName, rootType);
        for (Class<?> clazz : collectionTypes) {
            stream.alias(clazz.getSimpleName(), clazz);
        }
        Object bean = stream.fromXML(xml);
        return bean;
    }

    public static XStream xmlToBeanWithCDATA = new XStream(new XppDriver(new XmlFriendlyNameCoder()) {
        public HierarchicalStreamWriter createWriter(Writer out) {
            return new PrettyPrintWriter(out) {
                // 对所有xml节点的转换都增加CDATA标记
                boolean cdata = true;
                @SuppressWarnings("unchecked")
                public void startNode(String name, Class clazz) {
                    super.startNode(name, clazz);
                }
                protected void writeText(QuickWriter writer, String text) {
                    if (cdata) {
                        writer.write("<![CDATA[");
                        writer.write(text);
                        writer.write("]]>");
                    } else {
                        writer.write(text);
                    }
                }
            };
        }
    });
}
